#!/usr/bin/env python
# -*- coding: utf-8 -*-

from cStringIO import StringIO
import unittest

from ws9 import document, line


original_data = """The Zen of Python, by Tim Peters
    Beautiful is better than ugly.
Explicit is better than implicit.
\tSimple is better than complex.
\t\tComplex is better than complicated.
Flat is better than nested.
"""


class TestReprEndings(unittest.TestCase):
    
    def testCR(self):
        self.assertEqual(document.repr_endings(['\r']), 'CR')
    
    def testCRLF(self):
        self.assertEqual(document.repr_endings(['\r\n']), 'CR/LF')
    
    def testLF(self):
        self.assertEqual(document.repr_endings(['\n']), 'LF')
    
    def testCR_LF(self):
        self.assertEqual(document.repr_endings(['\r', '\n']), 'CR, LF')
    
    def testCR_CRLF(self):
        self.assertEqual(document.repr_endings(['\r', '\r\n']), 'CR, CR/LF')
    
    def testCR_CRLF_LF(self):
        self.assertEqual(document.repr_endings(['\r', '\r\n', '\n']),
            'CR, CR/LF, LF')
    
    def testCRLF_LF(self):
        self.assertEqual(document.repr_endings(['\n', '\r\n']), 'CR/LF, LF')


class TestReprIndents(unittest.TestCase):
    
    def testMixed(self):
        indent = '  \t  '
        self.assertEqual(document.repr_indents(indent), 'mixed')
    
    def testTab(self):
        indent = '\t\t'
        self.assertEqual(document.repr_indents(indent), 'tab')
    
    def testSpace(self):
        indent = '    '
        self.assertEqual(document.repr_indents(indent), 'space')
    
    def testNone(self):
        self.assertEqual(document.repr_indents(''), 'no')
    
    def testUnknown(self):
        self.assertEqual(document.repr_indents('hello'), 'unknown')


class TestDocument(unittest.TestCase):
    
    def setUp(self):
        self.document = document.Document(original_data)
    
    def testGetEndings(self):
        self.assertEqual(self.document.endings, '\n')
    
    def testSetEndings(self):
        self.document.endings = '\r\n'
        for doc_line in self.document:
            self.assertEqual(doc_line.ending, '\r\n')
        self.document.endings = '\n'
        self.document[0].ending = '\r\n'
        self.assertEqual(self.document.endings, frozenset(['\n', '\r\n']))
    
    def testDelEndings(self):
        del self.document.endings
        for doc_line in self.document:
            self.assertEqual(doc_line.ending, '\n')
    
    def testGetIndentType(self):
        self.assertEqual(self.document.indent_type, frozenset([' ', '\t']))
        self.document[0].indent = '\t    '
        self.assertEqual(self.document.indent_type,
            frozenset([' ', '\t', '\t ']))
    
    def testSetIndents(self):
        self.document.indent_type = ' '
        self.assertEqual(self.document[3].indent, '    ')
        self.assertEqual(self.document[4].indent, '        ')
        self.assertEqual(self.document.indent_type, ' ')
    
    def testDelIndents(self):
        del self.document.indent_type
        self.assertEqual(self.document[3].indent, '    ')
        self.assertEqual(self.document[4].indent, '        ')
        self.assertEqual(self.document.indent_type, ' ')
    
    def testGetStringClass(self):
        self.assertEqual(self.document.string_class, str)
        self.document[0] = line.UnicodeLine(self.document[0])
        self.assertEqual(self.document.string_class, set([str, unicode]))
    
    def testSetStringClass(self):
        self.document.string_class = unicode
        for doc_line in self.document:
            self.assert_(isinstance(doc_line, line.UnicodeLine))
        
    def testDelStringClass(self):
        for i in xrange(len(self.document)):
            if i % 2:
                self.document[i] = line.UnicodeLine(self.document[i])
        self.assertEqual(self.document.string_class, set([str, unicode]))
        del self.document.string_class
        self.assertEqual(self.document.string_class, str)
        for doc_line in self.document:
            self.assert_(isinstance(doc_line, line.StrLine))
    
    def testGetTabWidth(self):
        self.assertEqual(self.document.tab_width, 4)
    
    def testSetTabWidth(self):
        self.document.tab_width = 8
        for doc_line in self.document:
            self.assertEqual(doc_line.tab_width, 8)
    
    def testDelTabWidth(self):
        for i in xrange(len(self.document)):
            if i % 2:
                self.document[i].tab_width = 8
        self.assertEqual(self.document.tab_width, frozenset([4, 8]))
        del self.document.tab_width
        for doc_line in self.document:
            self.assertEqual(doc_line.tab_width, 4)
    
    def testRepr(self):
        self.assert_(repr(self.document).startswith('<Document at'))
        self.assert_(repr(self.document).endswith(
            '(LF line endings, mixed indentation)>'))
        self.document.endings = '\r'
        self.assert_(repr(self.document).endswith(
            '(CR line endings, mixed indentation)>'))
        self.document.indent_type = ' '
        self.assert_(repr(self.document).endswith(
            '(CR line endings, space indentation)>'))
        self.document[0].ending = '\n'
        self.assert_(repr(self.document).endswith(
            '(CR, LF line endings, space indentation)>'))
        self.document.indent_type = '\t'
        self.assert_(repr(self.document).endswith(
            '(CR, LF line endings, tab indentation)>'))
    
    def testStr(self):
        self.assertEqual(str(self.document), original_data)
    
    def testUnicode(self):
        self.assertEqual(unicode(self.document), unicode(original_data))


if __name__ == '__main__':
    unittest.main()
